/*
 * (#)InvocationSecurityMetadataSourceService.java 1.0  2013年7月15日 GMT+08:00
 */
package com.newtouch.web.security;

/**
 * @author 凌蒙
 * @version V1.0, 2013年7月15日 GMT+08:00
 * @since JDK1.6
 */
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Service;

import com.newtouch.model.FASResources;
import com.newtouch.model.FASRole;
import com.newtouch.service.FASResourcesService;
import com.newtouch.service.FASRoleService;
/*
 * 
 * 最核心的地方，就是提供某个资源对应的权限定义，即getAttributes方法返回的结果。
 * 注意，我例子中使用的是AntUrlPathMatcher这个path matcher来检查URL是否与资源定义匹配，
 * 事实上你还要用正则的方式来匹配，或者自己实现一个matcher。
 * 
 * 此类在初始化时，应该取到所有资源及其对应角色的定义
 * 
 * 说明：对于方法的spring注入，只能在方法和成员变量里注入，
 * 如果一个类要进行实例化的时候，不能注入对象和操作对象，
 * 所以在构造函数里不能进行操作注入的数据。
 */
@Service("InvocationSecurityMetadataSourceService")
public class InvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(InvocationSecurityMetadataSourceService.class);
	@Autowired
	private FASRoleService roleService ;
	@Autowired
	private FASResourcesService actionService; 
	
	//private UrlMatcher urlMatcher = new AntUrlPathMatcher();
	private static Map<String, Collection<ConfigAttribute>> resourceMap = null;
	@SuppressWarnings("static-access")
	public  void loadResourceDefine()throws Exception  {
		this.resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
		
		//通过数据库中的信息设置，resouce和role
		for (FASRole item:this.roleService.findAllFASRole()){
			Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
			ConfigAttribute ca = new SecurityConfig(item.getRoleName());
			atts.add(ca);
			List<FASResources> tActionList = actionService.findByRoleCode(item.getRoleCode());
			//把资源放入到spring security的resouceMap中
			for(FASResources tAction:tActionList){
				logger.debug("获得角色：["+item.getRoleName()+"]拥有的acton有："+tAction.getSysModuleLink());
				this.resourceMap.put(tAction.getSysModuleLink(), atts);
			}
		}
		
		/*//通过硬编码设置，resouce和role
		resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
		Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
		ConfigAttribute ca = new SecurityConfig("admin"); 
		atts.add(ca); 
		resourceMap.put("/jsp/admin.jsp", atts); 
		resourceMap.put("/swf/zara.html", atts);*/ 
		
	}
	// According to a URL, Find out permission configuration of this URL.
	private UrlMatcher urlMatcher = new AntUrlPathMatcher();
	public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
		if (logger.isDebugEnabled()) {
			logger.debug("getAttributes(Object) - start"); //$NON-NLS-1$
		}
		// guess object is a URL.
		String url = ((FilterInvocation) object).getRequestUrl();
		Iterator<String> ite = resourceMap.keySet().iterator();
		while (ite.hasNext()) {
			String resURL = ite.next();
			if (urlMatcher.pathMatchesUrl(url, resURL)) {
				Collection<ConfigAttribute> returnCollection = resourceMap.get(resURL);
				if (logger.isDebugEnabled()) {
					logger.debug("getAttributes(Object) - end"); //$NON-NLS-1$
				}
				return returnCollection;
			}
		}
		if (logger.isDebugEnabled()) {
			logger.debug("getAttributes(Object) - end"); //$NON-NLS-1$
		}
		return null;
	}
	public boolean supports(Class<?> clazz) {
		return true;
	}
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return null;
	}
}